;; Author: Torsten Stüber

;; input/output pointer $o: 16 i64 = 128 bytes
(func $car25519 (export "car25519")
	(param $o i32)

	(local $v i64)
	(local $c i64)

	(set_local $c (i64.const 1))
	(set_local $v (i64.add (i64.add (i64.load offset=0 (get_local $o)) (get_local $c)) (i64.const 65535)))
	(set_local $c (i64.shr_s (get_local $v) (i64.const 16)))
	(i64.store offset=0 (get_local $o) (i64.sub (get_local $v) (i64.shl (get_local $c) (i64.const 16))))
	(set_local $v (i64.add (i64.add (i64.load offset=8 (get_local $o)) (get_local $c)) (i64.const 65535)))
	(set_local $c (i64.shr_s (get_local $v) (i64.const 16)))
	(i64.store offset=8 (get_local $o) (i64.sub (get_local $v) (i64.shl (get_local $c) (i64.const 16))))
	(set_local $v (i64.add (i64.add (i64.load offset=16 (get_local $o)) (get_local $c)) (i64.const 65535)))
	(set_local $c (i64.shr_s (get_local $v) (i64.const 16)))
	(i64.store offset=16 (get_local $o) (i64.sub (get_local $v) (i64.shl (get_local $c) (i64.const 16))))
	(set_local $v (i64.add (i64.add (i64.load offset=24 (get_local $o)) (get_local $c)) (i64.const 65535)))
	(set_local $c (i64.shr_s (get_local $v) (i64.const 16)))
	(i64.store offset=24 (get_local $o) (i64.sub (get_local $v) (i64.shl (get_local $c) (i64.const 16))))
	(set_local $v (i64.add (i64.add (i64.load offset=32 (get_local $o)) (get_local $c)) (i64.const 65535)))
	(set_local $c (i64.shr_s (get_local $v) (i64.const 16)))
	(i64.store offset=32 (get_local $o) (i64.sub (get_local $v) (i64.shl (get_local $c) (i64.const 16))))
	(set_local $v (i64.add (i64.add (i64.load offset=40 (get_local $o)) (get_local $c)) (i64.const 65535)))
	(set_local $c (i64.shr_s (get_local $v) (i64.const 16)))
	(i64.store offset=40 (get_local $o) (i64.sub (get_local $v) (i64.shl (get_local $c) (i64.const 16))))
	(set_local $v (i64.add (i64.add (i64.load offset=48 (get_local $o)) (get_local $c)) (i64.const 65535)))
	(set_local $c (i64.shr_s (get_local $v) (i64.const 16)))
	(i64.store offset=48 (get_local $o) (i64.sub (get_local $v) (i64.shl (get_local $c) (i64.const 16))))
	(set_local $v (i64.add (i64.add (i64.load offset=56 (get_local $o)) (get_local $c)) (i64.const 65535)))
	(set_local $c (i64.shr_s (get_local $v) (i64.const 16)))
	(i64.store offset=56 (get_local $o) (i64.sub (get_local $v) (i64.shl (get_local $c) (i64.const 16))))
	(set_local $v (i64.add (i64.add (i64.load offset=64 (get_local $o)) (get_local $c)) (i64.const 65535)))
	(set_local $c (i64.shr_s (get_local $v) (i64.const 16)))
	(i64.store offset=64 (get_local $o) (i64.sub (get_local $v) (i64.shl (get_local $c) (i64.const 16))))
	(set_local $v (i64.add (i64.add (i64.load offset=72 (get_local $o)) (get_local $c)) (i64.const 65535)))
	(set_local $c (i64.shr_s (get_local $v) (i64.const 16)))
	(i64.store offset=72 (get_local $o) (i64.sub (get_local $v) (i64.shl (get_local $c) (i64.const 16))))
	(set_local $v (i64.add (i64.add (i64.load offset=80 (get_local $o)) (get_local $c)) (i64.const 65535)))
	(set_local $c (i64.shr_s (get_local $v) (i64.const 16)))
	(i64.store offset=80 (get_local $o) (i64.sub (get_local $v) (i64.shl (get_local $c) (i64.const 16))))
	(set_local $v (i64.add (i64.add (i64.load offset=88 (get_local $o)) (get_local $c)) (i64.const 65535)))
	(set_local $c (i64.shr_s (get_local $v) (i64.const 16)))
	(i64.store offset=88 (get_local $o) (i64.sub (get_local $v) (i64.shl (get_local $c) (i64.const 16))))
	(set_local $v (i64.add (i64.add (i64.load offset=96 (get_local $o)) (get_local $c)) (i64.const 65535)))
	(set_local $c (i64.shr_s (get_local $v) (i64.const 16)))
	(i64.store offset=96 (get_local $o) (i64.sub (get_local $v) (i64.shl (get_local $c) (i64.const 16))))
	(set_local $v (i64.add (i64.add (i64.load offset=104 (get_local $o)) (get_local $c)) (i64.const 65535)))
	(set_local $c (i64.shr_s (get_local $v) (i64.const 16)))
	(i64.store offset=104 (get_local $o) (i64.sub (get_local $v) (i64.shl (get_local $c) (i64.const 16))))
	(set_local $v (i64.add (i64.add (i64.load offset=112 (get_local $o)) (get_local $c)) (i64.const 65535)))
	(set_local $c (i64.shr_s (get_local $v) (i64.const 16)))
	(i64.store offset=112 (get_local $o) (i64.sub (get_local $v) (i64.shl (get_local $c) (i64.const 16))))
	(set_local $v (i64.add (i64.add (i64.load offset=120 (get_local $o)) (get_local $c)) (i64.const 65535)))
	(set_local $c (i64.shr_s (get_local $v) (i64.const 16)))
	(i64.store offset=120 (get_local $o) (i64.sub (get_local $v) (i64.shl (get_local $c) (i64.const 16))))
	(i64.store offset=0 (get_local $o) (i64.add (i64.load offset=0 (get_local $o)) (i64.mul (i64.const 38) (i64.sub (get_local $c) (i64.const 1)))))
)